package com.king.designpatterns.结构型模式.享元模式;

/**
 * 享元模式（Flyweight Pattern）是池技术的重要实现方式，可以降低大量重复的、细粒度的类在内存中的开销。
 *
 * 定义：使用共享对象可有效地支持大量的细粒度的对象。
 *
 * 状态：
 *      ■ 内部状态是存储在享元对象内部的、可以共享的信息，并且不会随环境改变而改变。
 *      ■ 外部状态是随环境改变而改变且不可以共享的状态。享元对象的外部状态必须由客户端保存，
 *          并在享元对象被创建之后，在需要使用的时候再传入到享元对象内部。
 *
 * 角色：
 *      ■ 抽象享元（Flyweight）角色：
 *          该角色对享元类进行抽象，需要外部状态的操作可以通过参数的形式将外部状态传入。
 *      ■ 具体享元（ConcreteFlyweight）角色：
 *          该角色实现抽象享元定义的业务，注意享元对象的内部状态必须与环境无关，从而使得享元对象可以在系统内共享。
 *      ■ 享元工厂（FlyweightFactory）角色：
 *          该角色就是构造一个池容器，负责创建和管理享元角色，并提供从池容器中获得对象的方法，保证享元对象可以被系统适当的共享。
 *          当一个客户端对象请求一个享元对象时，享元工厂角色会检查系统中是否已经有一个符合要求的享元对象。如果已经有了，
 *          享元工厂则提供这个已有的享元对象；否则创建一个合适的享元对象。
 *      ■ 客户端（Client）角色：
 *          该角色需要自行存储所有享元对象的外部状态。
 *
 * 优缺点：
 *      ■ 享元模式增加了系统的复杂性，需要分出外部状态和内部状态，而且内部状态具有固化特性，不应该随外部状态改变而改变，这使得程序的逻辑复杂化。
 *      ■ 享元模式将享元对象的状态外部化，而读取外部状态使得运行时间变长
 *
 * 场景：
 *      ■ 系统中有大量的相似对象，这些对象耗费大量的内存。
 *      ■ 细粒度的对象都具备较接近的外部状态，而且内部状态与环境无关，即对象没有特定身份。
 *      ■ 需要缓冲池的场景。
 *
 * @author king
 * @date 2021-06-08 14:28
 */
public class FlyweightPattern {
    public static void main(String[] args) {
        Chesspiece p1 = ChesspieceFactory.getChesspiece("黑");
        p1.put(1,1);
        Chesspiece p2 = ChesspieceFactory.getChesspiece("白");
        p2.put(2,2);
        Chesspiece p3 = ChesspieceFactory.getChesspiece("黑");
        p3.put(3, 3);
        Chesspiece p4 = ChesspieceFactory.getChesspiece("白");
        p4.put(4,4);
    }
}
